defmodule EliPhxPlayWeb.AccountsController do
  use EliPhxPlayWeb, :controller

  alias EliPhxPlay.Context.Accounts

@doc """
用户注册页面处理
POST /register
"""
def register(conn, %{"user" => user_params}) do
  case Accounts.register_user(user_params) do
    {:ok, _user} ->
      conn
      |> put_flash(:info, "注册成功！请使用您的账号登录")
      |> redirect(to: ~p"/login")

    {:error, :account_already_exists} ->
      # 创建包含用户输入数据的 changeset
      changeset = create_changeset_with_data(user_params)
      |> Ecto.Changeset.add_error(:account, "账号已存在")

      conn
      |> put_flash(:error, "注册失败")
      |> render(:register, changeset: changeset)

    {:error, changeset} ->
      # 直接使用返回的 changeset，包含验证错误和用户数据
      conn
      |> put_flash(:error, "注册失败，请检查输入信息")
      |> render(:register, changeset: changeset)
  end
end

# 辅助函数：创建包含用户数据的 changeset
defp create_changeset_with_data(params) do
  %EliPhxPlay.ChatSchema.Users{}
  |> EliPhxPlay.ChatSchema.Users.changeset(params)
  |> Map.put(:action, :validate)
end




def register_page(conn, _params) do
  # Phoenix 1.7+ 使用不同的渲染方式
  render(conn, :register)
end

  @doc """
  用户登录
  """
  def login(conn, %{"user" => %{"account" => account, "password" => password}}) do
    case Accounts.authenticate_user(account, password) do
      {:ok, user} ->
        conn
        |> put_session(:user_id, user.user_id)
        |> put_flash(:info, "登录成功！")
        |> redirect(to: ~p"/dashboard")

      {:error, :user_not_found} ->
        conn
        |> put_flash(:error, "用户不存在")
        |> render(:login)

      {:error, :invalid_password} ->
        conn
        |> put_flash(:error, "密码错误")
        |> render(:login)

      {:error, :user_suspended} ->
        conn
        |> put_flash(:error, "账号已被禁用")
        |> render(:login)
    end
  end

  def login(conn, _params) do
    render(conn, :login)
  end


  defp format_changeset_errors(changeset) do
    # 辅助函数：将 changeset 中的错误信息格式化为易读的格式
    # changeset.errors 是一个 Map，其中键是字段名，值是错误信息列表
    # 比如：%{account: ["账号不能为空"], password: ["密码长度至少为6位"]}

    # 使用 Enum.reduce() 函数遍历 changeset.errors
    # 将每个字段名和错误信息组合成一个新的 Map
    Enum.reduce(changeset.errors, %{}, fn {field, {msg, _}}, acc ->
      Map.put(acc, Atom.to_string(field), [msg])
    end)
  end


  defp user_info(conn) do
    user_info = Accounts.get_user(conn)
    render(conn, :user_info, user_info: user_info)
  end
end
